<?php
abstract class Base_Browser
{
  /**
   * Store object of current curl 
   * @var object
   */
  private $curl;
  /**
   * Variable with response headers
   * @var array
   */
  private $headers;
  /**
   * Variable with server result
   * @var string
   */
  private $header;
  
  /**
   * Class constructir
   */
  function __construct()
  {
    if(!class_exists ("DOMDocument", false) )
    {
      throw new Exception ("Class 'DOMDocument' does not exists.");
    }
    
    if(!class_exists ("DOMXPath", false) )
    {
      throw new Exception ("Class 'DOMXPath' does not exists.");
    }
    
    if(!function_exists("curl_exec"))
    {
      throw new Exception ("Curl extention does not exists.");
    }
    
    $this->curl = curl_init();
  }

  /**
   * Get type of content
   */
  public function getContentType ()
  {
    $content_type = $this->getHeader("Content-Type");
    
    return mb_substr($content_type, 0,  mb_strpos($content_type, "/"));
  }
  /**
   * Method to get current encoding from header
   */
  public function getEncoding ()
  {
    $varname      = " charset=";
    $content_type = $this->getHeader("Content-Type");
    
    $varposition = mb_strpos($content_type, $varname);
    
    if ($varposition)
    {
      $varposition += mb_strlen($varname);
            
      return mb_substr($content_type, $varposition);
    }
    
    return NULL;
  }
  /**
   * Method to get needed header value
   * @param $header
   */
  public function getHeader($header)
  {
    if(! isset($this->headers))
    {
      throw new Exception("Request for unknown header!");
    }
    
    return $this->headers[$header];
  }    
  /**
   * Read headers and store to common array 
   * @param resourse $curl
   * @param string $header
   */
  protected function doReadHeader($curl, $header)
  {
    $header_length = mb_strlen($header);
    $header        = trim($header);
    
    if(mb_strlen(trim($header)))
    {
      $delimiter_position = strpos($header, ":");
      
      if($delimiter_position === false)
      {
        $this->header = $header;
        
        return $header_length;
      }
      
      $key    = trim(substr($header, 0, $delimiter_position));
      $value  = trim(substr($header, $delimiter_position + 1));
      
      $this->headers[$key] = $value;
    }
    return $header_length;
  }  
 /**
   * Check for permanently moved page
   * @return boolean
   */
  public function isMovedPermanently()
  {
    $statuses = array("301", "302");
    
    foreach($statuses as $status)
    {
      if(strpos($this->header, $status) !== false)
      {
        return true;
      }
    }
    
    return false;
  }  
  /**
   * Get current page content
   * @param $url
   */
  public function getContent($url)
  {
    $options_curl = array();
    
    $options_curl[CURLOPT_URL]            = $url;
    $options_curl[CURLOPT_RETURNTRANSFER] = true;
    $options_curl[CURLOPT_HEADERFUNCTION] = array($this, 'doReadHeader');
    $options_curl[CURLOPT_USERAGENT]      = 'Googlebot/2.1 (+http://www.google.com/bot.html)';
    
    curl_setopt_array($this->curl, $options_curl);
    
    $content = curl_exec($this->curl);
    
    if(! mb_strlen($content))
    {
      if($this->isMovedPermanently())
      {
        $options_curl[CURLOPT_URL] = $this->getHeader("Location");
        
        curl_setopt_array($this->curl, $options_curl);
        
        $content = curl_exec($this->curl);
      }
    }
    // Return Dom document object
    return new ContentHtml($url, $content, "1.0", $this->getEncoding ());
  }
}
?>